/*************************************************
* Title：TinyToolKit
* Author：Opportunity 
* Discribe：定义有限状态机的接口
* CreateTime：2020-04-05 21:28:43
* Version：1.0
* Modify Recoder：
*************************************************/
using System;
using System.Collections.Generic;

namespace TinyToolKit.FSM
{
    public interface IFsmSystem<T> where T : class
    {
        /// <summary>
        /// 获取有限状态机的名称
        /// </summary>
        string Name { get; }

        /// <summary>
        /// 获取有限状态机的完整名称
        /// </summary>
        string FullName { get; }

        /// <summary>
        /// 获取有限状态机持有者
        /// </summary>
        T Owner { get; }

        /// <summary>
        /// 获取有限状态机的状态数量
        /// </summary>
        /// <value>The fsm state count.</value>
        int FsmStateCount { get; }

        /// <summary>
        /// 判断当前FSM是否正在运行，true表明正在运行，false表示暂停中
        /// </summary>
        bool IsRunning { get; }

        /// <summary>
        /// 判断当前FSM是否已经被销毁
        /// </summary>
        bool IsDestroyed { get; }

        /// <summary>
        /// 获取当前有限状态机的状态
        /// </summary>
        FsmState<T> CurrentState { get; }

        /// <summary>
        /// 获取当前状态的全名
        /// </summary>
        string CurrentStateName { get; }

        /// <summary>
        /// 获取当前状态持续时间
        /// </summary>
        float CurrentStateTime { get; }

        /// <summary>
        /// 开启指定的有限状态机
        /// </summary>
        /// <typeparam name="T2">需要被开启的状态类型</typeparam>
        bool Start<T2>() where T2 : FsmState<T>;

        /// <summary>
        /// 开启指定的有限状态机
        /// </summary>
        /// <param name="stateType">需要被开启的状态类型</param>
        bool Start(Type stateType);

        /// <summary>
        /// 判断是否存在该状态
        /// </summary>
        /// <returns><c>true</c>, 该状态存在, <c>false</c> 不存在</returns>
        /// <typeparam name="T2">需要判断的状态类型</typeparam>
        bool HasState<T2>() where T2 : FsmState<T>;

        /// <summary>
        /// 判断是否存在该状态
        /// </summary>
        /// <returns><c>true</c>, 该状态存在, <c>false</c>  不存在</returns>
        /// <param name="stateType">需要判断的状态类型</param>
        bool HasState(Type stateType);

        /// <summary>
        /// 获取有限状态机的状态
        /// </summary>
        /// <returns>返回该状态</returns>
        /// <typeparam name="T2">需要返回状态的类型.</typeparam>
        T2 GetState<T2>() where T2 : FsmState<T>;

        /// <summary>
        /// 获取有限状态机的状态
        /// </summary>
        /// <returns>返回该状态</returns>
        /// <param name="stateType">需要返回状态的类型</param>
        FsmState<T> GetState(Type stateType);

        /// <summary>
        /// 获取所有的状态
        /// </summary>
        /// <returns>返回该状态机所有的状态</returns>
        FsmState<T>[] GetAllStates();

        /// <summary>
        /// 获取所有的状态，states不能为Null
        /// </summary>
        /// <param name="states">返回该状态机所有的状态</param>
        void GetAllStates(List<FsmState<T>> states);

        /// <summary>
        /// 切换当前有限状态机的状态
        /// </summary>
        /// <param name="stateType">需要切换的目标状态</param>
        void ChangeState(Type stateType);

        /// <summary>
        /// 切换当前有限状态机的状态
        /// </summary>
        /// <typeparam name="T2">需要切换的目标状态</typeparam>
        void ChangeState<T2>() where T2 : FsmState<T>;

        /// <summary>
        /// 是否存在有限状态机数据
        /// </summary>
        bool HasData(string name);

        /// <summary>
        /// 获取有限状态机的数据
        /// </summary>
        object GetData(string name);

        /// <summary>
        /// 获取有限状态机的数据
        /// </summary>
        T2 GetData<T2>(string name);

        /// <summary>
        /// 设置有限状态机数据
        /// </summary>
        /// <param name="name">数据的名称</param>
        /// <param name="data">要存储的数据</param>
        void SetData(string name, object data);

        /// <summary>
        /// 设置有限状态机数据
        /// </summary>
        /// <param name="name">数据的名称.</param>
        /// <param name="data">要存储的数据</param>
        /// <typeparam name="T2">要存储的数据类型</typeparam>
        void SetData<T2>(string name, T2 data);

        /// <summary>
        /// 移除有限状态机数据
        /// </summary>
        /// <returns><c>true</c>, 数据移除成功, <c>false</c> 移除失败</returns>
        /// <param name="name">需要移除的数据名称</param>
        bool RemoveData(string name);

        /// <summary>
        ///暂停状态机的更新
        /// </summary>
        void Pause();

        /// <summary>
        ///恢复状态机的更新
        /// </summary>
        void Resume();
    }
}
